//		Written by Todd Thomas Copyright (c) 1995 by Todd Thomas.
//				Version 1.0.  All rights reserved.
//
//		This notice may not be removed from this source code.
//
//	This object is included in the MiscKit by permission from the author
//	and its use is governed by the MiscKit license, found in the file
//	"LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
//	for a list of all applicable permissions and restrictions.
//	

#import <appkit/appkit.h>
#import <misckit/MiscFile.h>
#import <misckit/MiscAppFile.h>
#import "MyNXBrowserCell.h"
#import "Inspector.subproj/FileInspector.h"
#import "MyController.h"


@implementation MyController

- init
{
	[super init];
	rootFile = [ [MiscFile alloc] initWithPath: "/"];
	
	// Used so we can create children of different classes depending upon
	// their extension. For this example, there is just one subclass of
	// MiscFile which will be used for any file that has the "app" extension.
	[rootFile setCreateChildrenUsingExtensions: YES];
	[MiscFile registerFileClass: [MiscAppFile class] forExtension: "app"];
	inspector = nil;
	
	return self;
}


- free
{
	[rootFile free];
	return [super free];
}


- updateDirectory: sender
{
	// Called when we click the "Update Directory" button.
  	id  selectedFile = [ [browser selectedCell] file];
  	int  selectedCol = [browser selectedColumn];
  
  	if ([selectedFile isDirectory])
	{
		[selectedFile updateChildren];
		selectedCol++;	
	 }
	else
		[ [ [selectedFile parents] objectAt: 0] updateChildren];

	[browser reloadColumn: selectedCol];	
	
	return self;
}


- showInspector: sender
{
	// Load the inspector if it hasn't been already.
	if (inspector == nil)
	{
		char  path[MAXPATHLEN+1];
		
		if ([ [NXBundle mainBundle] getPath: path forResource: "Inspector"
					ofType: "nib"])
			[NXApp loadNibFile: path owner: self];
		
	 }

	// Display the inspector window.
	[self inspectFile: nil];
	[ [inspector window] orderFront: nil];
	return self;
}


- inspectFile: sender
{
	// If the inspector is loaded then let it know there is a new
	// file to look at.
	if (inspector != nil)
	{
		if ([ [sender selectedCell] file] == nil)
			[inspector selectedFile: rootFile];
		else	
			[inspector selectedFile: [ [sender selectedCell ] file] ];
	 }
	return self;
}


- duplicateFile: sender
{	
	// When the menu item "Duplicate file" is clicked upon, get the selected
	// item and try to duplicate it.
	MiscFile  *selFile = [ [browser selectedCell] file];
	char  tmp[MAXPATHLEN+1];
	char  *ptr;
	
	if (selFile == nil)
		return self;
	
	strcpy (tmp, [selFile fullPath]);
	ptr = strrchr (tmp, '/');
	*(ptr+1) = '\0';
	
	strcat (tmp, "CopyOf");
	strcat (tmp, [selFile filename]);
	
	if ([selFile createCopyNamed: tmp] == nil)
		NXRunAlertPanel ("Oh no!", "Couldn't create the copy. Sorry.", 
						"OK", 0, 0);
	
	[self updateDirectory: nil];
	return self;
}
	
	
- createSymLink: sender
{
	// Create a symbolic link to the selected file in the browser.
	MiscFile  *selFile = [ [browser selectedCell] file];
	char  tmp[MAXPATHLEN+1];
	char  *ptr;
	
	if (selFile == nil)
		return self;
	
	strcpy (tmp, [selFile fullPath]);
	ptr = strrchr (tmp, '/');
	*(ptr+1) = '\0';
	
	strcat (tmp, "SymLinkOf");
	strcat (tmp, [selFile filename]);
	
	if ([selFile createSymbolicLinkNamed: tmp] == nil)
		NXRunAlertPanel ("Oh no!", "Couldn't create the symbolic link. Sorry.", 
						"OK", 0, 0);
	
	[self updateDirectory: nil];
	return self;
}


- createHardLink: sender
{
	// Create a hard link to the selected file in the browser.
	MiscFile  *selFile = [ [browser selectedCell] file];
	char  tmp[MAXPATHLEN+1];
	char  *ptr;
	
	if (selFile == nil)
		return self;
	
	strcpy (tmp, [selFile fullPath]);
	ptr = strrchr (tmp, '/');
	*(ptr+1) = '\0';
	
	strcat (tmp, "HardLinkOf");
	strcat (tmp, [selFile filename]);
	
	if ([selFile createHardLinkNamed: tmp] == nil)
		NXRunAlertPanel ("Oh no!", "Couldn't create the link. Sorry.", 
						"OK", 0, 0);
	
	[self updateDirectory: nil];
	return self;
}

@end


@implementation MyController (NibInitialization)

// Do some initialization (especially to the browser).

- awakeFromNib
{
	// Use new browser cell to keep track of underlying MiscFile each cell 
	// represents.
	[browser setCellClass: [MyNXBrowserCell class] ];
	
	// The delegate is set here instead of in IB because when it is set 
	// in IB, loadColumnZero gets called (from within drawSelf::) before 
	// this awakeFromNib does, and since the new browser cell isn't set 
	// yet, it crashes. I mailed it to Bug_NeXT.
	
	[browser setDelegate: self];
	[browser setTarget: self];
	[browser setAction: @selector(inspectFile:)];
	[browser loadColumnZero];
	return self;
}

@end


@implementation MyController (BrowserDelegate)

// Load up whatever column we are supposed to. If we are loading the
// first one just use the rootFile, else we have to ask the 
// rightmost selected cell to tell us the MiscFile it represents.

- (int)browser:sender fillMatrix:matrix inColumn:(int)column
{
  id  displayFile = nil;
  id  children = nil;
  id  child = nil;
  id  cell = nil;
  int  i;

	// determine which MiscFile to use   
	if (column == 0)	
		displayFile = rootFile;
	else
		// get the MiscFile represented by the rightmost selected cell
		displayFile = [ [browser selectedCell] file];
		
	children = [displayFile children];

	// Load up the matrix with the MiscFile's children.
		
	for (i=0; i<[children count]; i++)
	{
		[matrix insertRowAt: i];
		cell = [matrix cellAt: i :0];
		child = [children objectAt: i];
        [cell setStringValue: [child filename] ];
		[cell setFile: child];	// This is so each cell knows it's MiscFile
		[cell setLoaded: YES];
		[cell setLeaf: [child displayAsLeaf] ];
	 }

    return [children count];
}

@end

